// @ts-ignore
import colors from 'colors-console';

const si = require('../../ext/systeminformation');
const NetworkListener = {
    configInit: false,
    netStatesString: '{}',
    ipPool: new Map(),
    urlPool: new Map(),
    selfAddress: [],

    async init() {
        this.configInit = true;
        const selfAddress = await this.getSelfAddress();
        this.selfAddress = selfAddress;

        while (this.configInit) {
            const ips: string[] = [...this.ipPool.keys()];
            const urls: string[] = [...this.urlPool.keys()];

            for (let i = 0; i < ips.length; i++) {
                const ip = ips[i];

                const ms = selfAddress.includes(ip) ? 10 : await si.inetLatency(ip);

                const ipStates = this.ipPool.get(ip);
                if (ipStates.ms !== ms) {
                    if (ms !== 0) {
                        ipStates.ok = true;
                        ipStates.ms = ms;
                        typeof ipStates.reConnectCallBack === 'function' && ipStates.reConnectCallBack(ms);
                    } else {
                        ipStates.ok = false;
                        ipStates.ms = ms;
                        typeof ipStates.disConnectCallBack === 'function' && ipStates.disConnectCallBack(ms);
                    }
                }
            }


            for (let i = 0; i < urls.length; i++) {
                const url = urls[i];
                try {
                    const {status, ms} = await si.inetChecksite(url);
                    const urlStates = this.urlPool.get(url);

                    if (urlStates.status !== status) {
                        if (status === 408) {
                            console.warn('请求失败', urlStates.siteName, url);
                            urlStates.ok = false;
                            urlStates.status = status;
                            urlStates.ms = ms;
                            typeof urlStates.disConnectCallBack === 'function' && urlStates.disConnectCallBack(ms);
                        } else if (status !== 404) {
                            urlStates.ok = true;
                            urlStates.status = status;
                            urlStates.ms = ms;
                            typeof urlStates.reConnectCallBack === 'function' && urlStates.reConnectCallBack(ms);
                        } else {
                            console.warn('请求失败', urlStates.siteName, url);
                            urlStates.ok = false;
                            urlStates.status = status;
                            urlStates.ms = ms;
                            typeof urlStates.disConnectCallBack === 'function' && urlStates.disConnectCallBack(ms);
                        }
                        this.toLog();
                    }

                } catch (e) {
                    console.log('请求失败', url);
                }
            }


            await new Promise(resolve => setTimeout(resolve, 10_000));
        }
    },

    async ping(ip: string) {
        const startDate = new Date();
        const ms = this.selfAddress.includes(ip) ? 10 : await si.inetLatency(ip);
        return ms > 0 ? new Date().getTime() - startDate.getTime() : -1;
    },

    async getNetworkGatewayDefault() {
        return new Promise(resolve => {
            setTimeout(() => {
                resolve(null);
            }, 1000);
            si.networkGatewayDefault((res: any) => {
                resolve(res);
            });
        });
    },

    async getSelfAddress() {
        const interfaces = await si.networkInterfaces();
        return interfaces?.map((item: any) => item.ip4) || [];
    },

    // 每隔两秒
    addListenerIP(ip: string, reConnectCallBack?: Function, disConnectCallBack?: Function) {
        this.ipPool.set(ip, {ip: ip, ms: 0, reConnectCallBack, disConnectCallBack});
    },

    removeListenerIP(ip: string) {
        this.ipPool.delete(ip);
    },

    addListenerUrl(siteName: string, url: string, reConnectCallBack?: Function, disConnectCallBack?: Function) {
        this.urlPool.set(url, {siteName, url, ms: 0, reConnectCallBack, disConnectCallBack});
    },

    removeListenerUrl(url: string) {
        this.urlPool.delete(url);
    },

    getLiveIPState() {
        return [...this.ipPool.values()];
    },

    getServiceUrlState() {
        return [...this.urlPool.values()];
    },


    toLog() {
        const services = [...this.urlPool.values()];

        const statusLine = services.map(({siteName, ok}: any) => {
            const status = ok === undefined ? '⌛' : ok ? '✅' : '❌';
            return `${siteName}:${status}`;
        }).join('  │ ');

        const total = Object.keys(services).length;
        const running = Object.values(services).filter(s => s.ok).length;

        console.log(
            `\x1b[44m\x1b[37m${new Date().toLocaleString()}\x1b[0m ` +
            `${statusLine} ` +
            `│ \x1b[33m统计:\x1b[0m ${running}/${total}  │ ${total - running}异常`
        );

    }
};


// async function main() {
//     console.log(111);
//
//     const res = await NetworkListener.getNetworkGatewayDefault();
//     console.log(res);
//
//     console.log(123);
// }
// main();

export default NetworkListener;